package be.ipl.finito.tests;

import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertFalse;
import static org.testng.AssertJUnit.assertNotNull;
import static org.testng.AssertJUnit.assertTrue;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import be.ipl.finito.domaine.Joueur;
import be.ipl.finito.domaine.Partie;
import be.ipl.finito.usecases.GestionJoueur;
import be.ipl.finito.usecases.GestionPartie;

public class GestionPartieTest {

	private static GestionPartie gestionPartie;
	private static GestionJoueur gestionJoueur;

	private static Joueur joueur1, joueur2, joueur3, joueur4, joueur5;
	private static Partie partie1;
	private Partie partie2;

	@BeforeClass
	public void beforeClass() throws NamingException {
		Context jndi = new InitialContext();
		gestionPartie = (GestionPartie) jndi
				.lookup("ejb:Finito/GestionPartieImpl!be.ipl.finito.usecases.GestionPartie");
		gestionJoueur = (GestionJoueur) jndi
				.lookup("ejb:Finito/GestionJoueurImpl!be.ipl.finito.usecases.GestionJoueur");

		gestionJoueur.inscrireJoueur("joueur1", "1234", "nom", "prenom", "email");
		gestionJoueur.inscrireJoueur("joueur2", "1234", "nom", "prenom", "email");
		gestionJoueur.inscrireJoueur("joueur3", "1234", "nom", "prenom", "email");

		joueur1 = gestionJoueur.seConnecter("joueur1", "1234");
		joueur2 = gestionJoueur.seConnecter("joueur2", "1234");
	}

	@Test
	public void creerPartieTest() {
		partie1 = gestionPartie.creerPartie("Partie de test");
		assertNotNull(partie1);
	}

	@Test(dependsOnMethods = "creerPartieTest")
	public void commencerPartieSansJoueurTest() {
		assertFalse(
				"Une partie doit avoir au moins deux joueurs pour commencer",
				gestionPartie.commencerPartie(partie1));
	}

	@Test(dependsOnMethods = "creerPartieTest")
	public void rechercherPartieTest() {
		assertEquals(partie1, gestionPartie.rechercherPartie(partie1.getId()));
	}

	@Test(dependsOnMethods = "creerPartieTest")
	public void listerPartiesEnAttenteTest() {
		assertTrue(gestionPartie.listerPartiesEnAttente().contains(partie1));
	}

	@Test(dependsOnMethods = "commencerPartieSansJoueurTest")
	public void rejoindrePartieTest() {
		assertTrue(gestionPartie.rejoindrePartie(partie1, joueur1));
		assertFalse("Un joueur ne peut rejoindre une partie qu'une seule fois",
				gestionPartie.rejoindrePartie(partie1, joueur1));
	}

	@Test(dependsOnMethods = "rejoindrePartieTest")
	public void commencerPartieAvecUnJoueurTest() {
		assertFalse(
				"Une partie doit avoir au moins deux joueurs pour commencer",
				gestionPartie.commencerPartie(partie1));
	}

	@Test(dependsOnMethods = "commencerPartieAvecUnJoueurTest")
	public void commencerPartieAvecAssezDeJoueursTest() {
		gestionPartie.rejoindrePartie(partie1, joueur2);
		assertTrue(gestionPartie.commencerPartie(partie1));
	}

	@Test(dependsOnMethods = "commencerPartieAvecAssezDeJoueursTest")
	public void listerJoueursTest() {
		assertTrue(gestionPartie.listerJoueurs(partie1).contains(joueur1));
		assertTrue(gestionPartie.listerJoueurs(partie1).contains(joueur2));
	}

	@Test(dependsOnMethods = "listerJoueursTest")
	public void estEnCoursTest() {
		assertTrue(gestionPartie.estEnCours(partie1));
	}

	@Test(dependsOnMethods = "estEnCoursTest")
	public void partieCommenceeSiMaxjoueur() {
		joueur3 = gestionJoueur.inscrireJoueur("joueur3", "1234", "nom", "prenom", "email");
		joueur4 = gestionJoueur.inscrireJoueur("joueur4", "1234", "nom", "prenom", "email");
		joueur5 = gestionJoueur.inscrireJoueur("joueur5", "1234", "nom", "prenom", "email");

		partie2 = gestionPartie.creerPartie("partie2");
		gestionPartie.rejoindrePartie(partie2, joueur3);
		gestionPartie.rejoindrePartie(partie2, joueur4);
		gestionPartie.rejoindrePartie(partie2, joueur5);
		assertTrue(gestionPartie.estEnCours(partie2));
	}

	@Test(dependsOnMethods = "partieCommenceeSiMaxjoueur")
	public void rejoindreUnePartieCommencee() {
		Joueur joueur9 = gestionJoueur.inscrireJoueur("Joueur6", "1234", "nom", "prenom", "email");
		assertFalse(gestionPartie.rejoindrePartie(partie2, joueur9));
	}
	@Test(dependsOnMethods = "rejoindreUnePartieCommencee")
	public void terminerPartieTest() {
		assertTrue(gestionPartie.terminerPartie(partie1));
	}

}
